#ifndef __LADDERLOG__H__
#define __LADDERLOG__H__

#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include "Log.h"

#define __VAR_LADDER_LOG(var)    \
    _ladder_##var
#define _VAR_LADDER_LOG(var)    \
    __VAR_LADDER_LOG(var)
#define VAR_LADDER_LOG()    \
    _VAR_LADDER_LOG(__LINE__)

/****************************************************************/

#define FUN_LOG_INFO(fmt, args...) \
    INFO_LOG("%s: "fmt, __FUNCTION__, ##args)
#define FUN_LOG_DEBUG(fmt, args...) \
    DEBUG_LOG("%s: "fmt, __FUNCTION__, ##args)
#define FUN_LOG_WARNING(fmt, args...) \
    WARNING_LOG("%s: "fmt, __FUNCTION__, ##args)
#define FUN_LOG_ERROR(fmt, args...) \
    ERROR_LOG("%s: "fmt, __FUNCTION__, ##args)
#define FUN_LOG_FATAL(fmt, args...) \
    FATAL_LOG("%s: "fmt, __FUNCTION__, ##args)

/****************************************************************/

#define LADDER_LOG(fmt, args...) \
    char * VAR_LADDER_LOG() = (char *)_log_ladder();  \
    INFO_LOG("%s:"fmt, VAR_LADDER_LOG(), ##args); \
    free(VAR_LADDER_LOG());

#define LADDER_LOG_INFO(fmt, args...) \
    char * VAR_LADDER_LOG() = (char *)_log_ladder();  \
    INFO_LOG("%s:"fmt, VAR_LADDER_LOG(), ##args); \
    free(VAR_LADDER_LOG());

#define LADDER_LOG_DEBUG(fmt, args...) \
    char * VAR_LADDER_LOG() = (char *)_log_ladder();  \
    DEBUG_LOG("%s:"fmt, VAR_LADDER_LOG(), ##args); \
    free(VAR_LADDER_LOG());

#define LADDER_LOG_WARNING(fmt, args...) \
    char * VAR_LADDER_LOG() = (char *)_log_ladder();  \
    WARNING_LOG("%s:"fmt, VAR_LADDER_LOG(), ##args); \
    free(VAR_LADDER_LOG());

#define LADDER_LOG_ERROR(fmt, args...) \
    char * VAR_LADDER_LOG() = (char *)_log_ladder();  \
    ERROR_LOG("%s:"fmt, VAR_LADDER_LOG(), ##args); \
    free(VAR_LADDER_LOG());

#define LADDER_LOG_FATAL(fmt, args...) \
    char * VAR_LADDER_LOG() = (char *)_log_ladder();  \
    FATAL_LOG("%s:"fmt, VAR_LADDER_LOG(), ##args); \
    free(VAR_LADDER_LOG());

/****************************************************************/

#define FUN_LADDER_LOG(fmt, args...) \
    char * VAR_LADDER_LOG() = (char *)_log_ladder();  \
    INFO_LOG("%s%s: "fmt, VAR_LADDER_LOG(), __FUNCTION__, ##args); \
    free(VAR_LADDER_LOG());

#define FUN_LADDER_LOG_INFO(fmt, args...) \
    char * VAR_LADDER_LOG() = (char *)_log_ladder();  \
    INFO_LOG("%s%s: "fmt, VAR_LADDER_LOG(), __FUNCTION__, ##args); \
    free(VAR_LADDER_LOG());

#define FUN_LADDER_LOG_DEBUG(fmt, args...) \
    char * VAR_LADDER_LOG() = (char *)_log_ladder();  \
    DEBUG_LOG("%s%s: "fmt, VAR_LADDER_LOG(), __FUNCTION__, ##args); \
    free(VAR_LADDER_LOG());

#define FUN_LADDER_LOG_WARNING(fmt, args...) \
    char * VAR_LADDER_LOG() = (char *)_log_ladder();  \
    WARNING_LOG("%s%s: "fmt, VAR_LADDER_LOG(), __FUNCTION__, ##args); \
    free(VAR_LADDER_LOG());

#define FUN_LADDER_LOG_ERROR(fmt, args...) \
    char * VAR_LADDER_LOG() = (char *)_log_ladder();  \
    ERROR_LOG("%s%s: "fmt, VAR_LADDER_LOG(), __FUNCTION__, ##args); \
    free(VAR_LADDER_LOG());

#define FUN_LADDER_LOG_FATAL(fmt, args...) \
    char * VAR_LADDER_LOG() = (char *)_log_ladder();  \
    FATAL_LOG("%s%s: "fmt, VAR_LADDER_LOG(), __FUNCTION__, ##args); \
    free(VAR_LADDER_LOG());

/****************************************************************/

#define LADDER_START() \
    extern int _log_ladder_level;\
    extern int _log_ladder_space;\
    _log_ladder_level += _log_ladder_space;

#define LADDER_END() \
    _log_ladder_level -= _log_ladder_space;  \
    _log_ladder_level = ((_log_ladder_level<0)?0:_log_ladder_level);

char* _log_ladder();
void _print_ladder();


#endif  //!__LADDERLOG__H__